package com.party.mobile.biz.copartner;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.StringUtils;
import com.party.core.model.activity.Activity;
import com.party.core.model.activity.ActivityInfo;
import com.party.core.model.copartner.BrokerageItem;
import com.party.core.model.copartner.BrokerageStatusEnum;
import com.party.core.model.copartner.CopartnerLevel;
import com.party.core.model.distributor.DistributorDetail;
import com.party.core.model.distributor.DistributorRelation;
import com.party.core.model.distributor.DistributorRelationType;
import com.party.core.model.member.Member;
import com.party.core.model.member.MemberCopartnerCount;
import com.party.core.model.wallet.Withdrawals;
import com.party.core.service.activity.IActivityInfoService;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.copartner.IBrokerageItemService;
import com.party.core.service.copartner.ICopartnerLevelService;
import com.party.core.service.distributor.IDistributorCountService;
import com.party.core.service.distributor.IDistributorDetailService;
import com.party.core.service.distributor.IDistributorRelationService;
import com.party.core.service.mall.IMallOrderDetailService;
import com.party.core.service.member.IMemberCopartnerCountService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.wallet.biz.WithdrawalsBizService;
import com.party.mobile.biz.analyze.MemberCopartnerDetailBizService;
import com.party.mobile.biz.distributor.DistributorBizService;
import com.party.notify.notifyPush.officialPartner.ICopartnerNotifySendService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;
import java.util.Set;

/**
 * 佣金业务接口
 *
 * @author yifeng
 * @date 2018/10/10 0010
 * @time 下午 14:32
 */
@Service
public class BrokerageBizService {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private IDistributorRelationService distributorRelationService;
    @Autowired
    private IBrokerageItemService brokerageItemService;
    @Autowired
    private IDistributorDetailService distributorDetailService;
    @Autowired
    private IActivityInfoService activityInfoService;
    @Autowired
    private ICopartnerLevelService copartnerLevelService;
    @Autowired
    private IDistributorCountService distributorCountService;
    @Autowired
    private MemberCopartnerDetailBizService memberCopartnerDetailBizService;
    @Autowired
    private ICopartnerNotifySendService copartnerNotifySendService;
    @Autowired
    private IActivityService activityService;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private WithdrawalsBizService withdrawalsBizService;
    @Autowired
    private IMallOrderDetailService mallOrderDetailService;
    @Autowired
    private IMemberCopartnerCountService memberCopartnerCountService;
    @Autowired
    private DistributorBizService distributorBizService;

    /**
     * 插入佣金记录
     *
     * @param relation      分销关系
     * @param targetId      目标id
     * @param activity      众筹项目
     * @param brokerageType 佣金类型
     * @param authorMember  众筹者/报名者
     * @throws Exception
     */
    public void insertBrokerageItem(DistributorRelation relation, String targetId, Activity activity,
                                    Integer brokerageType, Member authorMember) throws Exception {
        // 一级分成
        // detail为空，说明众筹不是从分销来的。正常报名的众筹是没有分销数据的。
        if (null != relation && distributorBizService.isCrowOrCourse(relation.getType())) {
            ActivityInfo activityInfo = activityInfoService.findByActivityId(activity.getId());
            if (null == activityInfo || new Integer(0).equals(activityInfo.getIsDistribution())) {
                throw new Exception("该活动没有配置佣金");
            }
            // 是否可提现
            boolean isBegin = false;
            if (null != activityInfo.getWithdrawDate() && activityInfo.getWithdrawDate().before(new Date())) {
                isBegin = true;
            }

            CopartnerLevel copartnerLevel = copartnerLevelService.findByMemberId(relation.getDistributorId());
            if (null == copartnerLevel) {
                throw new Exception("该合伙人不在关系表中");
            }

            String activityId = activity.getId();

            BrokerageItem item = new BrokerageItem();
            item.setBrokerage(activityInfo.getDirectBrokerage().floatValue()); // 一级分成佣金
            item.setCheckStatus(BrokerageStatusEnum.TWO_WITHDRAW.getCode()); // 审核通过
            item.setTargetId(targetId);
            item.setPartnerId(copartnerLevel.getMemberId()); // 分销者
            item.setParentId("-1");
            item.setActivityId(activityId);
            item.setType(brokerageType);
            item.setWithdrawDate(activityInfo.getWithdrawDate());
            brokerageItemService.insert(item);

            try {
                // 修改统计数
                memberCopartnerDetailBizService.updateBrokerage(copartnerLevel.getMemberId(), activityInfo.getDirectBrokerage(),
                        false, isBegin, 0);
            } catch (Exception e) {
                logger.error("统计佣金异常", e);
            }

            try {
                copartnerNotifySendService.sendDirectBrokerage(copartnerLevel.getMemberId()
                        , activity.getTitle(), activityInfo.getDirectBrokerage()
                        , activityId, authorMember.getRealname(), brokerageType);
            } catch (Exception e) {
                logger.error("直接佣金推送异常", e);
            }

            if (StringUtils.isNotEmpty(copartnerLevel.getParentId())) {
                // 二级分成
                item = new BrokerageItem();
                item.setBrokerage(activityInfo.getIndirectBrokerage().floatValue()); // 二级分成佣金
                item.setCheckStatus(BrokerageStatusEnum.TWO_WITHDRAW.getCode()); // 审核通过
                item.setTargetId(targetId);
                item.setPartnerId(copartnerLevel.getMemberId()); // 分销者
                item.setParentId(copartnerLevel.getParentId()); // 来自下级
                item.setActivityId(activityId);
                item.setType(brokerageType);
                item.setWithdrawDate(activityInfo.getWithdrawDate());
                brokerageItemService.insert(item);

                try {
                    // 修改统计数
                    memberCopartnerDetailBizService.updateBrokerage(copartnerLevel.getParentId(), activityInfo.getIndirectBrokerage(), true, isBegin, 0);
                } catch (Exception e) {
                    logger.error("统计佣金异常", e);
                }

                try {
                    Member member = memberService.get(copartnerLevel.getMemberId());
                    copartnerNotifySendService.sendIndirectBrokerage(copartnerLevel.getParentId()
                            , activity.getTitle(), activityInfo.getIndirectBrokerage()
                            , member.getRealname(), brokerageType);
                } catch (Exception e) {
                    logger.error("间接佣金推送异常", e);
                }
            }
        }
    }

    /**
     * 插入佣金记录
     *
     * @param targetId      目标id
     * @param activityId    众筹项目id
     * @param brokerageType 佣金类型
     * @throws Exception
     */
    public void insertBrokerageItem(String targetId, String activityId, Integer brokerageType, String targetAuthorId) throws Exception {
        // 一级分成
        // detail为空，说明众筹不是从分销来的。正常报名的众筹是没有分销数据的。
        DistributorDetail detail = distributorDetailService.findByTargetId(targetId);
        if (null != detail) {
            DistributorRelation relation = distributorRelationService.get(detail.getDistributorRelationId());
            if (null != relation && (DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(relation.getType())
                    || DistributorRelationType.COURSE_DISTRIBUTION.getCode().equals(relation.getType()))) {
                ActivityInfo activityInfo = activityInfoService.findByActivityId(activityId);
                if (null == activityInfo || new Integer(0).equals(activityInfo.getIsDistribution())) {
                    throw new Exception("该活动没有配置佣金");
                }
                // 是否可提现
                boolean isBegin = false;
                if (null != activityInfo.getWithdrawDate() && activityInfo.getWithdrawDate().before(new Date())) {
                    isBegin = true;
                }

                CopartnerLevel copartnerLevel = copartnerLevelService.findByMemberId(relation.getDistributorId());
                if (null == copartnerLevel) {
                    throw new Exception("该合伙人不在关系表中");
                }

                Member targetAuthor = memberService.get(targetAuthorId);

                Activity activity = activityService.get(activityId);

                BrokerageItem item = new BrokerageItem();
                item.setBrokerage(activityInfo.getDirectBrokerage().floatValue()); // 一级分成佣金
                item.setCheckStatus(BrokerageStatusEnum.TWO_WITHDRAW.getCode()); // 审核通过
                item.setTargetId(targetId);
                item.setPartnerId(copartnerLevel.getMemberId()); // 分销者
                item.setParentId("-1");
                item.setActivityId(activityId);
                item.setType(brokerageType);
                item.setWithdrawDate(activityInfo.getWithdrawDate());
                brokerageItemService.insert(item);

                try {
//                    Double withdrawalTotal = withdrawalsBizService.getWithdrawalTotal(copartnerLevel.getMemberId(), Withdrawals.TYPE_BROKERAGE);
                    // 修改统计数
                    memberCopartnerDetailBizService.updateBrokerage(copartnerLevel.getMemberId(), activityInfo.getDirectBrokerage(),
                            false, isBegin, 0);
                } catch (Exception e) {
                    logger.error("统计佣金异常", e);
                }

                try {
                    copartnerNotifySendService.sendDirectBrokerage(copartnerLevel.getMemberId()
                            , activity.getTitle(), activityInfo.getDirectBrokerage()
                            , activityId, targetAuthor.getRealname(), brokerageType);
                } catch (Exception e) {
                    logger.error("直接佣金推送异常", e);
                }

                if (StringUtils.isNotEmpty(copartnerLevel.getParentId())) {
                    // 二级分成
                    item = new BrokerageItem();
                    item.setBrokerage(activityInfo.getIndirectBrokerage().floatValue()); // 二级分成佣金
                    item.setCheckStatus(BrokerageStatusEnum.TWO_WITHDRAW.getCode()); // 审核通过
                    item.setTargetId(targetId);
                    item.setPartnerId(copartnerLevel.getMemberId()); // 分销者
                    item.setParentId(copartnerLevel.getParentId()); // 来自下级
                    item.setActivityId(activityId);
                    item.setType(brokerageType);
                    item.setWithdrawDate(activityInfo.getWithdrawDate());
                    brokerageItemService.insert(item);

                    try {
//                        Double withdrawalTotal = withdrawalsBizService.getWithdrawalTotal(copartnerLevel.getParentId(), Withdrawals.TYPE_BROKERAGE);
                        // 修改统计数
                        memberCopartnerDetailBizService.updateBrokerage(copartnerLevel.getParentId(), activityInfo.getIndirectBrokerage(), true, isBegin, 0);
                    } catch (Exception e) {
                        logger.error("统计佣金异常", e);
                    }

                    try {
                        Member member = memberService.get(copartnerLevel.getMemberId());
                        copartnerNotifySendService.sendIndirectBrokerage(copartnerLevel.getParentId()
                                , activity.getTitle(), activityInfo.getIndirectBrokerage()
                                , member.getRealname(), brokerageType);
                    } catch (Exception e) {
                        logger.error("间接佣金推送异常", e);
                    }
                }
            }
        }
    }

    /**
     * 获取佣金数据
     *
     * @param memberId 用户id
     * @return
     */
    public Map<String, Object> getBrokerageData(String memberId) {
        Map<String, Object> resultMap = Maps.newHashMap();
        MemberCopartnerCount query = new MemberCopartnerCount();
        query.setMemberId(memberId);
        MemberCopartnerCount copartnerCount = memberCopartnerCountService.sum(query);

        // 可结算佣金（自己+下级）
        Double canBrokerageTotal = brokerageItemService.getMyBrokerage(memberId, BrokerageItem.STATUS_CAN_BROKERAGE, null, null, true);

        // 未结算佣金（自己+下级）
        Double remainBrokerageTotal = brokerageItemService.getMyBrokerage(memberId, BrokerageItem.STATUS_NOT_BROKERAGE, null, null, true);

        // 累计提现佣金
        Double withdrawalTotal = withdrawalsBizService.getWithdrawalTotal(memberId, Withdrawals.TYPE_BROKERAGE,null);

        // 可提现佣金
        double canWithdrawal = BigDecimalUtils.sub(canBrokerageTotal, withdrawalTotal);

        resultMap.put("totalMoney", copartnerCount.getTotalMoney());
        resultMap.put("brokerageTotal", copartnerCount.getTotalBrokerage());
        resultMap.put("withdrawalTotal", BigDecimalUtils.round(withdrawalTotal, 2));
        resultMap.put("canWithdrawalTotal", BigDecimalUtils.round(canWithdrawal, 2));
        resultMap.put("remainBrokerageTotal", BigDecimalUtils.round(remainBrokerageTotal, 2));
        return resultMap;
    }

    public Map<String, Object> getBrokerageData1(String memberId) {
        Map<String, Object> resultMap = Maps.newHashMap();

        // 可结算佣金（自己+下级）
        Double canBrokerageTotal = brokerageItemService.getMyBrokerage(memberId, BrokerageItem.STATUS_CAN_BROKERAGE, null, null, true);

        // 未结算佣金（自己+下级）
        Double remainBrokerageTotal = brokerageItemService.getMyBrokerage(memberId, BrokerageItem.STATUS_NOT_BROKERAGE, null, null, true);

        // 累计推广资金（众筹+课程）
        Set<Integer> types = Sets.newHashSet();
        types.add(DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode());
        types.add(DistributorRelationType.COURSE_DISTRIBUTION.getCode());
        Double totalMoney = distributorCountService.countTotalMoney(memberId, types);

        // 累计佣金（未结算+可提现）
        Double brokerageTotal = BigDecimalUtils.add(canBrokerageTotal, remainBrokerageTotal);

        // 累计提现佣金
        Double withdrawalTotal = withdrawalsBizService.getWithdrawalTotal(memberId, Withdrawals.TYPE_BROKERAGE,null);

        // 可提现佣金
        double canWithdrawalTotal = BigDecimalUtils.sub(canBrokerageTotal, withdrawalTotal);

        resultMap.put("canBrokerageTotal", BigDecimalUtils.round(canBrokerageTotal, 2));
        resultMap.put("remainBrokerageTotal", BigDecimalUtils.round(remainBrokerageTotal, 2));
        resultMap.put("totalMoney", BigDecimalUtils.round(totalMoney, 2));
        resultMap.put("brokerageTotal", BigDecimalUtils.round(brokerageTotal, 2));
        resultMap.put("withdrawalTotal", BigDecimalUtils.round(withdrawalTotal, 2));
        resultMap.put("canWithdrawalTotal", BigDecimalUtils.round(canWithdrawalTotal, 2));
        return resultMap;
    }

    /**
     * 获取可提现的佣金
     *
     * @param type     类型 1：余额 2：佣金 3：商城分销
     * @param memberId 用户id
     * @return
     */
    public Double getCanBrokerage(Integer type, String memberId) {
        Double brokerageTotal = 0d;
        if (Withdrawals.TYPE_BROKERAGE.equals(type)) { // CEO户外联盟分佣
            brokerageTotal = brokerageItemService.getMyBrokerage(memberId, BrokerageItem.STATUS_CAN_BROKERAGE, null, null, true);
        } else if (Withdrawals.TYPE_MALL.equals(type)) { // 商城分销提现
            brokerageTotal = mallOrderDetailService.getSumTotal(memberId); // 已完成订单
        }
        return null == brokerageTotal ? 0d : brokerageTotal;
    }
}
